package ifgi.potwc.ipt.ui;

import ifgi.potwc.ipt.R;
import ifgi.potwc.ipt.database.IptDatabase;
import ifgi.potwc.ipt.upload.IptUploadManager;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Environment;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.widget.Toast;
import au.com.bytecode.opencsv.CSVWriter;

import com.actionbarsherlock.app.SherlockPreferenceActivity;
import com.actionbarsherlock.view.MenuItem;

public class SettingsActivity extends SherlockPreferenceActivity
{
    // Identifier for the different dialogs
    private static final int DELETE_DATABASE_DIALOG = 12;
    private static final int EXPORT_DATABASE_DIALOG = 34;
    private static final int UPLOAD_DATABASE_DIALOG = 56;

    // Custom preferences
    private Preference deleteDatabasePref;
    private Preference exportDatabasePref;
    private Preference uploadDatabasePref;

    // Context
    private Context ctx;

    // Database
    private IptDatabase iptDb;
    private SQLiteDatabase db;

    // Upload Manager
    private IptUploadManager uploadManager;

    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
	super.onCreate(savedInstanceState);
	addPreferencesFromResource(R.xml.preferences);

	// Get the SherlockActionBar
	getSherlock().getActionBar().setDisplayHomeAsUpEnabled(true);

	// Initialize attributes
	ctx = getApplicationContext();
	iptDb = new IptDatabase(ctx);
	db = iptDb.getWritableDatabase();
	uploadManager = new IptUploadManager(ctx);

	// Initialize the custom preferences and set onClickListeners
	deleteDatabasePref = (Preference) findPreference("deleteDatabase");
	deleteDatabasePref
		.setOnPreferenceClickListener(new OnPreferenceClickListener()
		{
		    @Override
		    public boolean onPreferenceClick(Preference preference)
		    {
			showDialog(DELETE_DATABASE_DIALOG);

			return true;
		    }
		});

	exportDatabasePref = (Preference) findPreference("exportDatabase");
	exportDatabasePref
		.setOnPreferenceClickListener(new OnPreferenceClickListener()
		{
		    @Override
		    public boolean onPreferenceClick(Preference preference)
		    {
			showDialog(EXPORT_DATABASE_DIALOG);

			return true;
		    }
		});

	uploadDatabasePref = (Preference) findPreference("uploadDatabase");
	uploadDatabasePref
		.setOnPreferenceClickListener(new OnPreferenceClickListener()
		{
		    @Override
		    public boolean onPreferenceClick(Preference preference)
		    {
			showDialog(UPLOAD_DATABASE_DIALOG);

			return true;
		    }
		});
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
	switch (item.getItemId())
	{
	// In case of pressing the back-arrow on the left in the action bar
	// return to the MainActivity
	case android.R.id.home:
	    startActivity(new Intent(this, MainActivity.class));
	    return true;

	default:
	    return super.onOptionsItemSelected(item);
	}
    }

    // ***************************************************************************
    // Dialogs

    @SuppressWarnings("deprecation")
    @Override
    protected Dialog onCreateDialog(int id)
    {
	Builder builder = new AlertDialog.Builder(this);

	switch (id)
	{
	case DELETE_DATABASE_DIALOG:
	    // Create custom Delete Database Dialog
	    builder.setMessage("Do you really want to delete all database entries? This can not be undone!");
	    builder.setCancelable(true);
	    builder.setPositiveButton("Yes",
		    new DeleteDialogOkOnClickListener());
	    builder.setNegativeButton("No", new CancelOnClickListener());
	    AlertDialog deleteDialog = builder.create();
	    deleteDialog.show();
	    break;
	case EXPORT_DATABASE_DIALOG:
	    // Create custom Export Database Dialog
	    builder.setMessage("Do you really want to export all database entries to the SD-card?");
	    builder.setCancelable(true);
	    builder.setPositiveButton("Yes",
		    new ExportDialogOkOnClickListener());
	    builder.setNegativeButton("No", new CancelOnClickListener());
	    AlertDialog exportDialog = builder.create();
	    exportDialog.show();
	    break;
	case UPLOAD_DATABASE_DIALOG:
	    // Create custom Export Database Dialog
	    builder.setMessage("Do you really want to upload all database entries to Cosm?");
	    builder.setCancelable(true);
	    builder.setPositiveButton("Yes",
		    new UploadDialogOkOnClickListener());
	    builder.setNegativeButton("No", new CancelOnClickListener());
	    AlertDialog uploadDialog = builder.create();
	    uploadDialog.show();
	    break;
	}

	return super.onCreateDialog(id);
    }

    /**
     * OnClickListener for the Dialogs' Cancel-button.
     * 
     * @author saschak.
     */
    private final class CancelOnClickListener implements
	    DialogInterface.OnClickListener
    {
	public void onClick(DialogInterface dialog, int which)
	{
	    // Do nothing
	}
    }

    /**
     * OnClickListener for the Delete Database Dialog's OK-button.
     * 
     * @author saschak.
     */
    private final class DeleteDialogOkOnClickListener implements
	    DialogInterface.OnClickListener
    {
	public void onClick(DialogInterface dialog, int which)
	{
	    // Delete the application's database
	    getApplicationContext().deleteDatabase(IptDatabase.DB_NAME);

	    Toast.makeText(getApplicationContext(), R.string.databaseDeleted,
		    Toast.LENGTH_SHORT).show();
	}
    }

    /**
     * OnClickListener for the Export Database Dialog's OK-button.
     * 
     * @author saschak.
     */
    private final class ExportDialogOkOnClickListener implements
	    DialogInterface.OnClickListener
    {
	@Override
	public void onClick(DialogInterface dialog, int which)
	{
	    // Export database tabels as *.csv files
	    exportDatabaseTable(IptDatabase.ACC);
	    exportDatabaseTable(IptDatabase.BRI);
	    exportDatabaseTable(IptDatabase.HUM);
	    exportDatabaseTable(IptDatabase.LAT);
	    exportDatabaseTable(IptDatabase.LON);
	    exportDatabaseTable(IptDatabase.TMP);

	    String filePath = Environment.getExternalStorageDirectory()
		    .getPath() + "/ifgiParcelTracker/";

	    Toast.makeText(getApplicationContext(),
		    "Database exported to " + filePath, Toast.LENGTH_LONG)
		    .show();
	}
    }

    /**
     * OnClickListener for the Upload Database Dialog's OK-button.
     * 
     * @author saschak.
     */
    private final class UploadDialogOkOnClickListener implements
	    DialogInterface.OnClickListener
    {
	public void onClick(DialogInterface dialog, int which)
	{
	    // Upload the application's database to Cosm
	    uploadManager.uploadDatabase();
	}
    }

    // ***************************************************************************
    // Exporting Database

    /**
     * Exports all data for the given datastream as .csv file to the SD-card
     * directory /ifgiParcelTracker.
     * 
     * @param _datastream
     */
    public void exportDatabaseTable(String _datastream)
    {
	// Directory on external storage
	File exportDir = new File(Environment.getExternalStorageDirectory(),
		"ifgiParcelTracker");

	// In case the directory does not exist
	if (!exportDir.exists())
	{
	    // Create directory
	    exportDir.mkdirs();
	}

	// Table name
	String tableName = _datastream + IptDatabase.TABLE_TAG;

	// Create new .csv file
	File file = new File(exportDir, tableName + ".csv");

	try
	{
	    file.createNewFile();

	    CSVWriter csvWriter = new CSVWriter(new FileWriter(file));

	    Cursor cursor = db.rawQuery("SELECT * FROM " + tableName, null);

	    csvWriter.writeNext(cursor.getColumnNames());

	    while (cursor.moveToNext())
	    {
		String[] rowEntries = new String[5];

		for (int i = 0; i < 5; i++)
		{
		    rowEntries[i] = cursor.getString(i);
		}

		csvWriter.writeNext(rowEntries);
	    }

	    csvWriter.close();

	    cursor.close();
	}
	catch (IOException e)
	{
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
    }

    // ***************************************************************************
    // Shared Preferences

    /**
     * Returns the Application's SharedPreferences.
     * 
     * @param _ctxWrapper
     * @return The application's SharedPreferences.
     */
    public static final SharedPreferences getPrefs(
	    final ContextWrapper _ctxWrapper)
    {
	return _ctxWrapper.getSharedPreferences(_ctxWrapper.getPackageName()
		+ "_preferences", MODE_PRIVATE);
    }
}